package com.quectel.sdk.hik8700.entranceguard;

import com.fasterxml.jackson.databind.JsonNode;
import com.quectel.sdk.hik8700.AbstractHik8700BaseClient;
import com.quectel.sdk.hik8700.entranceguard.model.*;
import com.quectel.util.common.JacksonUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.function.Consumer;

/**
 * 在这里编写说明
 *
 * @author: rananxin
 * @email: ryan.ran@quectel.com
 * @date: 2022-10-19 11:01:00
 */
public class EntranceGuardClient extends AbstractHik8700BaseClient {

    private static final String SUCCESS_CODE = "0";
    private static final Logger LOGGER = LoggerFactory.getLogger(EntranceGuardClient.class);

    public PersonFaceInfoResp personFaceInfoByCode(String personNo) {
        final String path = "/openapi/service/base/person/getFingerAndFaceInfo";

        Map<String, Object> params = new HashMap<>();
        String defaultUserId = requester.getDefaultUserId();
        params.put("opUserUuid", defaultUserId);
        params.put("personNo", personNo);

        String response = requester.post(path, params);
        JsonNode respJson = JacksonUtils.parse(response);
        String code = respJson.get("errorCode").asText();
        if (!SUCCESS_CODE.equals(code)) {
            LOGGER.error("海康 获取人员人脸信息异常 response {}", response);
        }
        if (respJson.findValue("data") == null) {
            return null;
        }
        JsonNode value = respJson.findValue("data");
        if (value != null) {
            return JacksonUtils.parse(JacksonUtils.toJsonString(value), PersonFaceInfoResp.class);
        }
        return null;
    }

    public PersonInfoResp personInfoById(String personId) {
        final String path = "/openapi/service/base/person/getPersonInfosByIds";

        Map<String, Object> params = new HashMap<>();
        String defaultUserId = requester.getDefaultUserId();
        params.put("opUserUuid", defaultUserId);
        params.put("personIds", personId);

        String response = requester.post(path, params);
        JsonNode respJson = JacksonUtils.parse(response);
        String code = respJson.get("errorCode").asText();
        if (!SUCCESS_CODE.equals(code)) {
            LOGGER.error("海康 获取人员基本信息异常 response {}", response);
        }
        if (respJson.findValue("data") == null) {
            return null;
        }
        JsonNode value = respJson.findValue("data");
        if (value != null && value.size() > 0) {
            return JacksonUtils.parse(JacksonUtils.toJsonString(value.get(0)), PersonInfoResp.class);
        }
        return null;
    }

    /**
     * 获取时间段内的人脸抓拍
     *
     * @param startTime
     * @param endTime
     * @param pageHandlerFunction 每一页的处理
     * @return
     */
    public void fetchFaceRecord(List<String> codes, Date startTime, Date endTime, Consumer<List<AccessRecordResp>> pageHandlerFunction) {
        final String path = "/openapi/service/acs/event/getDoorEventsHistory";

        final int fetchSize = 999;
        Map<String, Object> params = new HashMap<>();
        params.put("eventType", 197162);
        params.put("pageSize", fetchSize);
        String defaultUserId = requester.getDefaultUserId();
        params.put("opUserUuid", defaultUserId);
        params.put("startTime", startTime.getTime());
        params.put("endTime", endTime.getTime());
        if (CollectionUtils.isNotEmpty(codes)) {
            params.put("doorUuids", StringUtils.join(codes, ","));
        }
        int pageNo = 0;
        while (true) {
            params.put("pageNo", ++pageNo);
            String resp = requester.post(path, params);
            JsonNode respJson = JacksonUtils.parse(resp);
            String code = respJson.get("errorCode").asText();
            if (!SUCCESS_CODE.equals(code)) {
                LOGGER.error("海康 获取进出记录资源异常 response {}", resp);
                break;
            }
            if (respJson.findValue("data") == null) {
                break;
            }
            JsonNode value = respJson.findValue("data").findValue("list");
            if (value == null) {
                break;
            }
            pageHandlerFunction.accept(JacksonUtils.parseArray(JacksonUtils.toJsonString(value), AccessRecordResp.class));
            if (value.size() < fetchSize) {
                break;
            }
        }
    }

    /**
     * 获取门禁资源列表
     * 涉及的api包括：
     * 分页获取监控点资源 path:/openapi/service/acs/res/getACDevices
     *
     * @return 全部监控点资源集合
     */
    public List<SyncGuardResp> drawResources() {
        final int fetchSize = 999;
        Map<String, Object> params = new HashMap<>();
        params.put("pageSize", fetchSize);
        params.put("opUserUuid", requester.getDefaultUserId());

        final String path = "/openapi/service/acs/res/getDoors";

        List<SyncGuardResp> result = new ArrayList<>();
        int pageNo = 0;
        while (true) {
            params.put("pageNo", ++pageNo);
            String response = requester.post(path, params);
            JsonNode respJson = JacksonUtils.parse(response);
            String code = respJson.get("errorCode").asText();
            if (!SUCCESS_CODE.equals(code)) {
                LOGGER.error("海康 获取门禁资源异常 response {}", response);
                break;
            }
            if (respJson.findValue("data") == null) {
                break;
            }
            JsonNode value = respJson.findValue("data").findValue("list");
            if (value == null) {
                break;
            }
            result.addAll(JacksonUtils.parseArray(JacksonUtils.toJsonString(value), SyncGuardResp.class));
            if (value.size() < fetchSize) {
                break;
            }
        }
        LOGGER.debug("海康 获取门禁资源成功 total {}", result.size());
        return result;
    }

    /**
     * 获取门禁资源列表
     * 涉及的api包括：
     * 分页获取监控点资源 path:/openapi/service/acs/res/getACDevices
     *
     * @return 全部人员资源集合
     */
    public void drawPersons( Consumer<List<SyncPersonResp>> pageHandlerFunction) {
        final int fetchSize = 999;
        Map<String, Object> params = new HashMap<>();
        params.put("pageSize", fetchSize);
        params.put("opUserUuid", requester.getDefaultUserId());

        final String path = "/openapi/service/base/person/getPersonInfosEx";

        List<SyncPersonResp> result = new ArrayList<>();
        int pageNo = 0;
        while (true) {
            params.put("pageNo", ++pageNo);
            String response = requester.post(path, params);
            JsonNode respJson = JacksonUtils.parse(response);
            String code = respJson.get("errorCode").asText();
            if (!SUCCESS_CODE.equals(code)) {
                LOGGER.error("海康 获取人员资源异常 response {}", response);
                break;
            }
            if (respJson.findValue("data") == null) {
                break;
            }
            JsonNode value = respJson.findValue("data").findValue("list");
            if (value == null) {
                break;
            }
            pageHandlerFunction.accept(JacksonUtils.parseArray(JacksonUtils.toJsonString(value), SyncPersonResp.class));
            if (value.size() < fetchSize) {
                break;
            }
        }
        LOGGER.debug("海康 获取人员资源成功 total {}", result.size());
    }

}
